home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
a86b.arc
/
EQU.DOC
< prev
next >
Wrap
Text File
|
1986-06-22
|
5KB
|
111 lines
---EQU.DOC---
The EQU Directive
Syntax: symbol-name EQU expression
symbol-name EQU built-in-symbol
symbol-name EQU INT n
The expression field may specify an operand of any type that could appear as an
operand to an instruction.
As a simple example, suppose you are writing a program that manipulates a table
containing 100 names and that you want to refer to the maximum number of names
throughout the source file. You can, of course, use the number 100 to refer to
this maximum each time, as in MOV CX,100, but this approach suffers from two
weaknesses. First of all, 100 can mean a lot of things; in the absence of
comments, it is not obvious that a particular use of 100 refers to the maximum
number of names. Secondly, if you extend the table to allow 200 names, you will
have to locate each 100 and change it to a 200. Suppose, instead, that you
define a symbol to represent the maximum number of names with the following
statement:
MAX_NAMES EQU 100
Now when you use the symbol MAX_NAMES instead of the number 100 (for example,
MOV CX,MAX_NAMES), it will be obvious that you are referring to the maximum
number of names in the table. Also, if you decide to extend the table, you need
only change the 100 in the EQU directive to a 200 and every reference to
MAX_NAMES will reflect the change.
You could also take advantage of A86's strong-typing, by changing MAX_NAMES to
a variable:
MAX_NAMES DB ?
or even an indexed quantity:
MAX_NAMES EQU [BX+1]
Because the A86 language is strongly-typed, the instruction for loading
MAX_NAMES into the CX-register remains exactly the same in all cases: simply
MOV CX,MAX_NAMES.
Equates to Built-In Symbols
A86 allows you to define synonyms for any of the assembler reserved-symbols,
by EQUating an alternate name of your choosing, to that symbol. For example,
suppose you were coding a source module that is to be incorporated into
several different programs. In some programs, a certain variable will exist
in the code segment. In others, it will exist in the stack segment. You want
to address the variable in the common source module, but you don't know which
segment-override to use. The solution is to declare a synonym, QS, for the
segment register. QS will be defined by each program: the code-segment program
will have a QS EQU CS at the top of it; the stack-segment program will have
QS EQU SS. The source module can use QS as an override, just as if it were
CS or SS. The code would be, for example, QS MOV AL,VARNAME.
The NIL Prefix
A86 provides a mnemonic, NIL, that generates no code. NIL can be used as
a prefix to another instruction (which will have no effect on that instruction),
or it can appear by itself on a line. NIL is provided to extend the example
in the previous section, to cover the possibility of no-overrides. If your
source module goes into a program that fits into 64K, so that all the segment
registers have the same value, then code QS EQU NIL at the top of that program.
Interrupt Equates
A86 allows you to equate your own name to an INT-instruction with a specific
interrupt-number. For example, if you place TRAP EQU INT 3 at the top of
your program, you can use the name TRAP as a synonym for INT 3 (the debugger
trap on the 8086).
Duplicate Definitions
A86 contains the unique feature of duplicate definitions. We have already
discussed local symbols, which can be redefined to different values without
restriction. Local symbols are the only symbols that can be redefined.
However, any symbol can be defined more than once, as long as the symbol is
defined to be the same value and type in each definition.
This feature has two uses. First, it eases modular program development. For
example, if two independently-developed source files both use the symbol ESC to
stand for the ASCII code for ESCAPE, they can both contain the declaration ESC
EQU 01B, with no problems if they are combined into the same program.
The second use for this feature is assertion-checking. Your delibarate
re-declaration of a symbol name is an assertion that the value of the symbol has
not changed; and you want the assembler to issue you an error message if it has
changed. Example: suppose you have declared a table of options in your DATA
segment; and you have another table of initial values for those options in your
CODE segment. If you come back months later and add an option to your tables,
you want to be reminded to update both tables in the same way. You should
declare your tables as follows:
DATA SEGMENT
OPTIONS:
.
.
OPT_COUNT EQU $-OPTIONS ; OPT_COUNT is the size of the table
CODE SEGMENT
OPT_INITS:
.
.
OPT_COUNT EQU $-OPT_INITS ; second OPT_COUNT had better be the same!